#ifndef __TOYM__BASE__SINGLETON_H__
#define __TOYM__BASE__SINGLETON_H__

#include <atomic>
#include <mutex>

template<typename T>
class Singleton {
public:
    static 
    T* getInstance() {
        if (m_instance.load(std::memory_order::memory_order_acquire) == nullptr) {
            std::unique_lock<std::mutex> lock(m_mutex);
            if (m_instance.load(std::memory_order::memory_order_acquire) == nullptr) {
                m_instance.store(new T(), std::memory_order::memory_order_release);
            }
        }
        return m_instance.load();
    }
private:
    static
    std::atomic<T*> m_instance;

    static
    std::mutex m_mutex;
};

template<typename T>
std::atomic<T*> Singleton<T>::m_instance(nullptr);

template<typename T>
std::mutex Singleton<T>::m_mutex;

#endif //__TOYM__BASE__SINGLETON_H__